package com.awccis.common.pool;

import cn.jpush.api.push.model.PushPayload;
import com.awccis.common.session.DriverSession;
import com.awccis.common.utils.MapUtils;
import com.awccis.common.utils.MessagePushUtil;
import com.awccis.driver.model.DriverUpdateInfo;

import java.util.*;

/**
 * @author: txp
 * @date: 2018/5/27 on 下午9:26
 * @since: 1.0
 * @description:
 */
public class DriverPool {

    /**
     * map
     */
    private static Map<String, DriverSession> map = new HashMap<String, DriverSession>();

    /**
     * 向内存池中存入司机的信息Session
     *
     * @param sessionId     webSocket的sessionID
     * @param driverSession driverSession
     */
    public static void addDriverSession(String sessionId, DriverSession driverSession) {
        if (!map.containsKey(sessionId)) {
            map.put(sessionId, driverSession);
        }
    }

    /**
     * 删除driverSeesion
     *
     * @param sessionId sessionId
     */
    public static void deleteDriverSession(String sessionId) {
        if (map.containsKey(sessionId)) {
            map.remove(sessionId);
        }
    }

    /**
     * 通过Phone删除司机的session
     *
     * @param phone driverPhone
     * @return 删除结果
     */
    public static boolean deleteDriverByPhone(String phone) {
        Iterator<Map.Entry<String, DriverSession>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, DriverSession> entry = entries.next();
            if (phone.equals(entry.getValue().getDriverPhone())) {
                map.remove(entry.getKey());
                return true;
            }
        }
        return false;
    }

    /**
     * 通过driverId删除driverSession
     *
     * @param driverId driverId
     * @return 删除结果
     */
    public static boolean deleteDriverById(int driverId) {
        Iterator<Map.Entry<String, DriverSession>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, DriverSession> entry = entries.next();
            if (driverId == entry.getValue().getDriverId()) {
                map.remove(entry.getKey());
                return true;
            }
        }
        return false;
    }

    /**
     * 通过nickName删除driverSession
     *
     * @param nickName nickName
     * @return 执行结果
     */
    public static boolean deleteDriverByNickName(int nickName) {
        Iterator<Map.Entry<String, DriverSession>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, DriverSession> entry = entries.next();
            if (nickName == entry.getValue().getDriverNickName()) {
                map.remove(entry.getKey());
                return true;
            }
        }
        return false;
    }

    /**
     * 通过SessionId判断内存池中时候已经存在此session
     *
     * @param sessionId sessionId
     * @return 判断结果
     */
    public static boolean isExist(String sessionId) {
        return map.containsKey(sessionId);
    }

    /**
     * 通过nickName判断内存池中是否已经存在此session
     *
     * @param nickName nickName
     * @return 判断结果
     */
    public static boolean isContainByNickname(int nickName) {
        for (DriverSession driverSession : map.values()) {
            if (nickName == driverSession.getDriverNickName() && driverSession.getSession() != null) {
                return true;
            }
        }
        return false;
    }

    /**
     * 通过phone判断内存池中是否已经存在此session
     *
     * @param phone phone
     * @return 判断结果
     */
    public static boolean isContainByPhone(String phone) {
        for (DriverSession driverSession : map.values()) {
            if (phone.equals(driverSession.getDriverPhone())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 通过driverId判断此内存池中是否已经存在此session
     *
     * @param driverId driverId
     * @return 判断结果
     */
    public static boolean isContainById(int driverId) {
        for (DriverSession driverSession : map.values()) {
            if (driverId == driverSession.getDriverId()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 通过phone向指定对的driver推送message
     *
     * @param phone   phone
     * @param message message
     * @return 执行结果
     */
    public static boolean sendMessageByPhone(String phone, String message) {
        for (DriverSession driverSession : map.values()) {
            if (phone.equals(driverSession.getDriverPhone())) {
                driverSession.getSession().getAsyncRemote().sendText(message);
                return true;
            }
        }
        return false;
    }

    /**
     * 通过driverId向指定的driver推送message
     *
     * @param id      id
     * @param message message
     * @return 执行结果
     */
    public static boolean sendMessageById(int id, String message) {
        for (DriverSession driverSession : map.values()) {
            if (id == driverSession.getDriverId()) {
                driverSession.getSession().getAsyncRemote().sendText(message);
                return true;
            }
        }
        return false;
    }

    /**
     * 通过nickName向指定的driver推送message
     *
     * @param nickName nickName
     * @param message  message
     * @return 执行结果
     */
    public static boolean sendMessageByNickName(int nickName, String message) {

        for (DriverSession driverSession : map.values()) {
            if (nickName == driverSession.getDriverNickName()) {
                if(driverSession.getSession()==null){
                    return false;
                }
                else{
                    driverSession.getSession().getAsyncRemote().sendText(message);
                    return true;
                }

            }
        }
        return false;
    }

    /**
     * 更改driver的当前location
     *
     * @param driverId driverId
     * @param lat      lat 纬度
     * @param lng      lng 经度
     * @return 执行结果
     */
    public static boolean updateLocation(int driverId, double lat, double lng) {
        for (DriverSession driverSession : map.values()) {
            if (driverId == driverSession.getDriverId()) {
                driverSession.setLocation(lat, lng);
                return true;
            }
        }
        return false;
    }

    /**
     * 通过driverId更改当前的driver工作状态
     *
     * @param driverId driverId
     * @param isWork   true or false
     * @return 执行结果
     */
    public static boolean updateIsWorkById(int driverId, boolean isWork) {
        DriverSession session = getSessionById(driverId);
        if (session != null) {
            session.setWork(isWork);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 通过phone更改当前在线driver的工作状态
     *
     * @param phone  phone
     * @param isWork true or false
     * @return 执行结果
     */
    public static boolean updateIsWorkByPhone(String phone, boolean isWork) {
        DriverSession session = getSessionByPhone(phone);
        if (session != null) {
            session.setWork(isWork);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 通过nickName更改当前在线driver的工作状态
     *
     * @param nickName nickName
     * @param isWork   true or false
     * @return 执行结果
     */
    public static boolean updateIsWorkByNickName(int nickName, boolean isWork) {
        DriverSession session = getSessionByNickName(nickName);
        if (session != null) {
            session.setWork(isWork);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 通过driverID更改driver是否要听单、收单
     *
     * @param driverId driverId
     * @param isReady  isReady true 为听单 false为收单
     * @return 更改结果
     */
    public static boolean updateIsReadyByDriverId(int driverId, boolean isReady) {
        DriverSession session = getSessionById(driverId);
        if (session != null) {
            session.setReady(isReady);
            return true;
        } else {
            return false;
        }
    }

    public static DriverSession getDriverSession(String sessionId) {
        return map.get(sessionId);
    }

    public static List<DriverSession> getAllOnlineDriver() {
        List<DriverSession> list = new LinkedList();
        for (DriverSession driverSession : map.values()) {
            list.add(driverSession.Dclone());
        }
        return list;
    }

    /**
     * 所有在线的driver
     *
     * @return list
     */
    public static List<DriverSession> getSimpleAllOnlineDriver() {
        List<DriverSession> list = new LinkedList();
        for (DriverSession driverSession : map.values()) {
            list.add(driverSession.SDclone());
        }
        return list;
    }

    /**
     * 所有在线的以工作状态为条件的driver
     *
     * @param isWork
     * @return
     */
    private static List<DriverSession> getDrivers(boolean isWork) {
        List<DriverSession> list = new LinkedList();
        for (DriverSession driverSession : map.values()) {
            if (driverSession.isWork() == isWork) {
                list.add(driverSession.Dclone());
            }
        }
        return list;
    }

    /**
     * 根据不同的信息，获取到当前内存中符合要求的司机
     *
     * @param isReady 是否听单
     * @param isWork  是否在工作
     * @param lat     纬度
     * @param lng     经度
     * @param carType 车类型
     * @param userNum 核载人数
     * @return list
     */
    private static List<DriverSession> getDrivers(boolean isReady, boolean isWork, double lat, double lng, String carType, int userNum) {
        List<DriverSession> list = new LinkedList();
        for (DriverSession driver : map.values()) {
            if (driver.isWork() == isWork
                    && driver.getCarLoadNum() >= userNum
                    && driver.isReady() == isReady
                    && driver.getDriverRange() >= MapUtils.GetDistance(lat, lng, driver.getLat(), driver.getLng()) / 1000
                    ) {
                if (carType.equals("%")) {
                    list.add(driver.Dclone());
                } else {
                    if (carType.equals(driver.getCarType())) {
                        list.add(driver.Dclone());
                    }
                }
            }
        }
        return list;
    }

    /**
     * 通过driverId获取内存中的driverSession对象
     *
     * @param driverId driverId
     * @return driverSession
     */
    public static DriverSession getSessionById(int driverId) {
        for (DriverSession session : map.values()) {
            if (driverId == session.getDriverId()) {
                return session;
            }
        }
        return null;
    }

    /**
     * 通过phone获取内存中的driverSession对象
     *
     * @param phone phone
     * @return driverSession
     */
    public static DriverSession getSessionByPhone(String phone) {
        for (DriverSession session : map.values()) {
            if (phone.equals(session.getDriverPhone())) {
                return session;
            }
        }
        return null;
    }

    /**
     * 通过nickName获取内存中的driverSession对象
     *
     * @param nickName nickName
     * @return driverSession
     */
    public static DriverSession getSessionByNickName(int nickName) {
        for (DriverSession session : map.values()) {
            if (nickName == session.getDriverNickName()) {
                return session;
            }
        }
        return null;
    }

    /**
     * 获取在线的前十个距离最近的司机
     *
     * @param lat     纬度
     * @param lng     经度
     * @param carType 车类型
     * @param userNum 核载人数
     * @return list
     */
    public static List<DriverSession> getTop10(double lat, double lng, String carType, int userNum) {

        List list = getDrivers(true, false, lat, lng, carType, userNum);

        Collections.sort(list, new Comparator<DriverSession>() {
            @Override
            public int compare(DriverSession o1, DriverSession o2) {
                return (int)
                        (
                                MapUtils.GetDistance(lat, lng, o1.getLat(), o1.getLng())
                                        -
                                        MapUtils.GetDistance(lat, lng, o2.getLat(), o2.getLng())
                        );
            }
        });

        if (list.size() >= 10) {
            return list.subList(0, 10);
        } else {
            return list;
        }

    }

    /**
     * 更改内存中的driverInfo
     *
     * @param driverUpdateInfo driverUpdateInfo
     * @return 更改结果
     */
    public static boolean updateInfo(DriverUpdateInfo driverUpdateInfo) {
        DriverSession driver = getSessionById(driverUpdateInfo.getDriverId());
        if (driver != null) {
            driver.setDriverAliasName(driverUpdateInfo.getDriverAliasName());
            driver.setDriverPhone(driverUpdateInfo.getDriverPhone());
            driver.setDriverRange(driverUpdateInfo.getDriverRange());
            driver.setCarBrand(driverUpdateInfo.getCarBrand());
            driver.setCarLoadNum(driverUpdateInfo.getCarLoadNum());
            driver.setCarPlateNum(driverUpdateInfo.getCarPlateNum());
            driver.setCarType(driverUpdateInfo.getCarType());
            return true;
        } else {
            return false;
        }

    }

}
